#ifndef _OBJECT_CLASS_H

#define _OBJECT_CLASS_H

#include "common.h"
#include "utils.h"
#include "header_obj.h"
#include "obj_fn.h"
#include "obj_string.h"
#include "meta_obj.h"
#include "obj_range.h"
#include "obj_map.h"
#include "obj_thread.h"

typedef enum 
{
    MT_NONE, // 空方法，并不等同于undefined
    MT_PRIMITIVE, // 在vm中用c实现的原生方法
    MT_SCRIPT, // 脚本中定义的方法
    MT_FN_CALL, // 有关函数对象的调用方法，用来实现函数重载
} MethodType; // 方法类型

#define VT_TO_VALUE(vt) \
    ((Value) {vt, { 0 }})

#define BOOL_TO_VALUE(boolean) (boolean ? VT_TO_VALUE(VT_TRUE): VT_TO_VALUE(VT_FALSE))
#define VALUE_TO_BOOL(value) ((value).value_type == VT_TRUE ? true: false)

#define NUM_TO_VALUE(num) ((Value){VT_NUM, {num}})
#define VALUE_TO_NUM(value) value.num

#define OBJ_TO_VALUE(obj_ptr) ({ \
    Value value; \
    value.value_type = VT_OBJ; \
    value.obj_header = (ObjHeader *)(obj_ptr); \
    value; \
})

#define VALUE_TO_OBJ(value)             (value.obj_header)
#define VALUE_TO_OBJSTR(value)          ((ObjString *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJFN(value)           ((ObjFn *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJCLOSURE(value)      ((ObjClosure *)VALUE_TO_OBJ(value))
#define VALUE_TO_CLASS(value)           ((Class *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJRANGE(value)        ((ObjRange *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJINSTANCE(value)     ((ObjInstance *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJLIST(value)         ((ObjList *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJMAP(value)          ((ObjMap *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJTHREAD(value)       ((ObjThread *)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJMODULE(value)       ((ObjModule *)VALUE_TO_OBJ(value))

#define VALUE_IS_UNDEFINED(value) ((value).value_type == VT_UNDEFINED)
#define VALUE_IS_NUL(value)       ((value).value_type == VT_NULL)
#define VALUE_IS_TRUE(value)      ((value).value_type == VT_TRUE)
#define VALUE_IS_FALSE(value)     ((value).value_type == VT_FALSE)
#define VALUE_IS_NUM(value)       ((value).value_type == VT_NUM)
#define VALUE_IS_OBJ(value)       ((value).value_type == VT_OBJ)

#define VALUE_IS_CERTAIN_OBJ(value, obj_type)   (VALUE_IS_OBJ(value) && VALUE_TO_OBJ(value)->type == obj_type)
#define VALUE_IS_OBJSTR(value)                  (VALUE_IS_CERTAIN_OBJ(value, OT_STRING))
#define VALUE_IS_OBJINSTANCE(value)             (VALUE_IS_CERTAIN_OBJ(value, OT_INSTANCE))
#define VALUE_IS_OBJCLOSURE(value)              (VALUE_IS_CERTAIN_OBJ(value, OT_CLOSURE))
#define VALUE_IS_OBJRANGE(value)                (VALUE_IS_CERTAIN_OBJ(value, OT_RANGE))
#define VALUE_IS_CLASS(value)                   (VALUE_IS_CERTAIN_OBJ(value, OT_CLASS))
#define VALUE_IS_0(value)                       (VALUE_IS_NUM(value) && (value).num == 0)

// 原生方法指针
typedef bool (*Primitive)(VM *vm, Value *args);

typedef struct 
{
    MethodType type; // union中的值由type的值决定
    union 
    {
        Primitive orim_fn;
        // 指向脚本代码编译后的ObjClosure或ObjFn
        ObjClosure *obj; 
    };
} Method;

DECLARE_BUFFER_TYPE(Method)

// 类是对象的模板
struct class
{
    ObjHeader obj_header;
    struct class *super_class; // 父类
    uint32_t field_num; // 本类的字段数，包括基类的字段数
    MethodBuffer methods; // 本类的方法
    ObjString *name; // 类名
};  // 对象类

typedef union
{
    uint64_t bits64;
    uint32_t bits32[2];
    double num;
} Bits64;  // 用来存储64位数据

#define CAPACITY_GROW_FACTOR 4  // map和list扩容的系数
#define MIN_CAPACITY 64 // map扩容数据

bool value_is_equal(Value a, Value b);
Class* new_raw_class(VM *vm, const char *name, uint32_t field_num);
#endif